/*
 * Project: Sudoku Explainer
 * Copyright (C) 2006-2007 Nicolas Juillerat
 * 
 * Project: Sudoku Hint Engine for Android
 * Copyright (C) 2010-2013 Emanuel Moecklin
 * 
 * Available under the terms of the Lesser General Public License (LGPL)
 */
package com.onegravity.sudoku.solver.rules.uniqueness;

import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.onegravity.sudoku.solver.HintResource;
import com.onegravity.sudoku.solver.HintType;
import com.onegravity.sudoku.solver.R;
import com.onegravity.sudoku.solver.core.Rule;
import com.onegravity.sudoku.solver.data.Cell;
import com.onegravity.sudoku.solver.data.ImmutableCell;
import com.onegravity.sudoku.solver.data.Region;
import com.onegravity.sudoku.solver.util.HtmlLoader;
import com.onegravity.sudoku.solver.util.ValuesFormatter;

public class Bug4Hint extends BugHint implements Rule {

	private static final long serialVersionUID = 372886999274312923L;
	
	private final Cell bugCell1;
    private final Cell bugCell2;
    private final Map<Cell, BitSet> extraValues;
    private final BitSet allExtraValues;
    private final int value; // removable value appearing on both cells
    private final Region region;


    public Bug4Hint(Map<Cell, BitSet> removablePotentials,
            Cell bugCell1, Cell bugCell2, Map<Cell, BitSet> extraValues,
            BitSet allExtraValues, int value, Region region) {
        super(removablePotentials);
        this.bugCell1 = bugCell1;
        this.bugCell2 = bugCell2;
        this.extraValues = extraValues;
        this.allExtraValues = allExtraValues;
        this.value = value;
        this.region = region;
    }

    @Override
    public Collection<Cell> getSelectedCells(HintType hintType) {
    	return (hintType!=HintType.SMALL_CLUE) ? Arrays.asList(new Cell[] {bugCell1, bugCell2}) : null;
    }

    @Override
    public Map<Cell, BitSet> getAddedPotentials(HintType hintType, int viewNum) {
        return (hintType==HintType.HINT) ? extraValues : null;
    }

    @Override
    public Map<Cell, BitSet> getSecondarySelectedPotentials(HintType hintType, int viewNum) {
        Map<Cell, BitSet> result = new HashMap<Cell, BitSet>();
        BitSet cand = new BitSet();
        cand.set(value);
        result.put(bugCell1, cand);
        result.put(bugCell2, cand);
        return (hintType==HintType.HINT) ? result : null;
    }

    @Override
    public Map<ImmutableCell, BitSet> getRemovedPotentials(HintType type) {
        return (type==HintType.HINT) ? super.getRemovedPotentials(type) : null;
    }

    @Override
    public Region[] getRegions(HintType type) {
    	return (type==HintType.HINT) ? new Region[] {this.region} : null;
    }

    @Override
    public double getDifficulty() {
        return 5.7;
    }

    protected HintResource getResource() {
    	return HintResource.BUG_4;
    }

    protected int getType() {
    	return 4;
    }

    protected String getAppendixString() {
    	return bugCell1.toString() + "," + bugCell2.toString() + " " + HintResource.getString(R.string.on) + " " + value; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    }

    @Override
    public String getHintHtml(HintType hintType) {
        String andString = HintResource.getString(R.string.and);
        String orString = HintResource.getString(R.string.or);
        String result = HtmlLoader.loadHtml(HintResource.BUG_4.hint(hintType));
        String bugValuesAnd = ValuesFormatter.formatValues(allExtraValues, " " + andString + " "); //$NON-NLS-1$ //$NON-NLS-2$
        String bugCellsAnd = ValuesFormatter.formatCells(new Cell[] {bugCell1, bugCell2}, " " + andString + " "); //$NON-NLS-1$ //$NON-NLS-2$
        String bugCellsOr = ValuesFormatter.formatCells(new Cell[] {bugCell1, bugCell2}, " " + orString + " "); //$NON-NLS-1$ //$NON-NLS-2$
        String bugValuesOr = ValuesFormatter.formatValues(allExtraValues, " " + orString + " "); //$NON-NLS-1$ //$NON-NLS-2$
        String lockedValue = Integer.toString(value);
        String regionName = region.toString();
        BitSet removable = new BitSet();
        for (BitSet r : getRemovablePotentials().values())
            removable.or(r);
        String removableValues = ValuesFormatter.formatValues(removable, " " + andString + " "); //$NON-NLS-1$ //$NON-NLS-2$
        return HtmlLoader.format(result, bugValuesAnd, bugCellsAnd, bugCellsOr, bugValuesOr, lockedValue, regionName, removableValues);
    }

}